home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 121_01 / tel.c < prev    next >
Text File  |  1985-08-19  |  23KB  |  1,118 lines

  1. /*
  2. HEADER: CUG 121.??;
  3.  
  4.     TITLE:    tel - dumb terminal + file xfer;
  5.     VERSION:    1.0;
  6.     DATE:    01/06/86;
  7.     DESCRIPTION: "Tel is a considerably modified version of Telnet v2.3, as
  8.         distributed with v1.46 of the BDS C compiler.  The following
  9.         features have been added: multiple files may be transmitted or
  10.         received by one command, directories may be listed, and the
  11.         quit command hangs up a hayes smartmodem.  To accommodate
  12.         these changes, some of the command names have been changed.
  13.         This program uses a modem to emulate a dumb terminal.
  14.         Incoming data may be buffered in memory and written to disk, 
  15.         data may be transmitted from disk to the modem, or files may
  16.         be formally transferred in a "checksum" mode with automatic
  17.         handshaking and buffering.";
  18.     KEYWORDS:    terminal, modem, emulate, file transfer;
  19.     SYSTEM:    CP/M;
  20.     FILENAME:    TEL.C;
  21.     WARNINGS:    "Requires local.c and files.c for link.
  22.         The checksum file transfer does not follow the XMODEM
  23.         protocol.
  24.         Variable baud rate support is present, but commented out
  25.         (hardware-specific coding would be required to implement it).
  26.         Tel assumes that the CP/M console is much faster than the
  27.         modem (e.g. a 1200+ baud console with a 300 baud modem).";
  28.     SEE-ALSO:    CALL.C, TELNET.C, TL370.C;
  29.     AUTHORS:    Leor Zolman, Leo Kenen, Cal Thixton, Mike W. Meyer;
  30.     COMPILERS:    BDS-C 1.50;
  31. */
  32.  
  33. #include <bdscio.h>    /* System, h'ware constants            */
  34. #include <hardware.h>
  35.  
  36. #ifdef MULL    /* muellers version if MULL is defined.            */
  37.  
  38. #define TITLE "Mulltel version 1.5    12/3/80 tj"
  39. #define    INITB    3    /* 1200 baud initially                */
  40. #define    SSPECIAL '\\'    /* escape character initially            */
  41.  
  42. #else
  43.  
  44. #define TITLE "Telnet version 3.0-Intersystems    10/25/80 (mwm)\n"
  45. #define    SSPECIAL 29    /* Initial escape character ^]            */
  46. #define    INITB    5    /* 4800 baud initially. See setbaud()        */
  47.  
  48. #endif
  49.  
  50. #define    SELDSK    14    /* change logged in disk    */
  51. #define    DIRFRST    17    /* search for first occurance of a file */
  52. #define    DIRNEXT    18    /* search for next occurance of a file */
  53. #define    CURRDSK    25    /* return currently logged in disk    */
  54. #define    maxfiles    64    /* maximun # of file to send as once */
  55.  
  56. /*
  57.     The following #defines need not be changed:
  58. */
  59.  
  60. #define    ACK    0x06    /* Ascii ACK for handshaking    */
  61. #define    NAK    0x15
  62. #define    EOT    0x04    /* End of transmission        */
  63. #define    ETX    0x03    /* Abort Transmission        */
  64. #define    STX    0x02    /* Beginning of next filename to send    */
  65. #define    NUL    0x0    /* end of file name    */
  66. #define PHA    0xfd    /* for phase checking    */
  67. #define CR    0x0d    /* carriage return    */
  68. #define LF    0x0a    /* line feed        */
  69. #define NL    '\n'    /* god knows, compiler dependent!    */
  70.  
  71. /*
  72.     File Control Block structure
  73. */
  74.  
  75. struct    FCB    {
  76.     char    entry,        /* entry type. assumed 0    */
  77.         name[8],    /* file name    */
  78.         type[3],    /* file type    */
  79.         extent,        /* which entention is this one?    */
  80.         na,naa,        /* not used (??)    */
  81.         count,        /* record count    */
  82.         map[16],    /* disk allocation map    */
  83.         next;        /* next record to read    */
  84.     };
  85.  
  86. /*
  87.     External variable declarations:
  88. */
  89.  
  90. char    SPECIAL;    /* current SPECIAL or escape character        */
  91. char    rflag;        /* receiving file open flag            */
  92. char    tflag;        /* transmitting file open flag            */
  93. char    chflag;        /* checksumming enabled flag            */
  94. char    cflag;        /* text-collection enabled flag         */
  95. char    pflag;        /* pausing flag                 */
  96. char    spflag;        /* stripping parity bit flag            */
  97. char    nflag;        /* recognizing nulls flag            */
  98. char    fflag;        /* true if changing CR-LF's into
  99.                 just CR when transmitting        */
  100. char    lastc;        /* last char transmitted            */
  101. char    dodflag;    /* true if displaying outging data        */
  102. char    didflag;    /* true if displaying incoming data        */
  103. char    hdflag;        /* true if effectively working in half-duplex     */
  104. char    hd_sav;        /* save flag when transmitting or receiving     */
  105. char    abortf;        /* true when file I/O aborted            */
  106. char    rbuf[BUFSIZ];     /* file I/O buffer for incoming data file     */
  107. char    tbuf[SECSIZ];     /* sector buffer for file being transmitted    */
  108. char    tmp[20];    /* tempory holding place for file name        */
  109. char    rname[20];     /* name of receiving file            */
  110. char    tname[20];     /* name of transmitting file            */
  111. int    rfd, tfd;    /* file descriptors                */
  112. char    *cptr;        /* pointer to free space in buf         */
  113. unsigned free;        /* number of bytes free in buf            */
  114. int     bcount;        /* counts bytes in current block when checksumming */
  115. int     scount;        /* Number of sectors sent/received        */
  116. int     checksum;    /* the checksum value itself            */
  117. char    timoutf;    /* 1 if time-out happens while waiting for modem data*/
  118. char    *i;        /* odd-job char pointer             */
  119. int     dod_sav, did_sav;    /* scratch variables            */
  120. unsigned bufspace;    /* # of bytes available for collection buffer in ram */
  121. char    toupper();    /* This makes for better code             */
  122. char    fcb[34];    /* file control block                */
  123. struct {            /* so i can't use initializers        */
  124.     char    rate[5],    /* readable baud rate            */
  125.         hex;
  126.     } bauds [7];
  127. char    current;        /* current baud rate being used        */
  128. char    files[maxfiles][17];    /* files to send             */
  129. char    leftover;    /* number of file to send             */
  130. char    thisdisk;    /* currently logged in disk            */
  131. char    *buf;        /* text collection pointer; will
  132.                 point to the location just after itself */
  133.  
  134. /*
  135.     place for main.c
  136. */
  137.  
  138. main()
  139. {
  140.     char    c, c2;
  141.     int n;
  142.  
  143.     init();
  144.  
  145.     while(1) {
  146.         if (abortf) {
  147.             if (rflag) 
  148.                 rclose();
  149.             if (tflag) 
  150.                 tabort();
  151.             reset();
  152.             abortf = 0;
  153.             }
  154.         if (tflag && xmit()) {
  155.             printf("\nTransmission complete.\n");
  156.             close(tfd);
  157.             reset();
  158.             }
  159.         if (abortf) 
  160.             continue;
  161.         if (miready()) {
  162.             c = c2 = getmod();
  163.             if (spflag)
  164.                 c &= 0x7f;
  165.             if (tflag && (c == ETX)) {
  166.                 printf("Receiver has aborted;\n");
  167.                 abortf = 1;
  168.                 continue;
  169.                 }
  170.             if (didflag && (c || nflag) && (c != CPMEOF))
  171.                 display(c);
  172.             if (cflag && !pflag) {
  173.                 if (c || nflag)
  174.                     if (!free) {
  175.                          printf("**BUFFER FULL**\007\007");
  176.                          rdump(0);
  177.                         }
  178.                     else {
  179.                         *cptr++ = c;
  180.                         free--;
  181.                         }
  182.                 if (chflag) {
  183.                     checksum += c2;
  184.                     bcount++;
  185.                     if (bcount == SECSIZ) {
  186.                         bcount = 0;
  187.                         outmod(checksum >> 8);
  188.                         outmod(checksum);
  189.                         checksum = 0;
  190.                         c = getmod();
  191.                         if(c == STX) {
  192.                             getname(tmp);
  193.                             rdump(0);
  194.                             rclose();
  195.                             scount=0;
  196.                             strcpy(rname,tmp);
  197.                             if(opento()) {
  198.                                 outmod(ETX);
  199.                                 abortf=1;
  200.                                 }
  201.                             outmod(PHA);
  202.                             }
  203.                         else if (c == EOT) {
  204.                             rdump(0);
  205.                             rclose();
  206.                             reset();
  207.                             printf("\n%s received OK\n",rname);
  208.                             }
  209.                         else if (c == ACK) {
  210.                             if (cptr > buf+1000) 
  211.                                 rdump(0);
  212.                             if (!didflag) 
  213.                                 printf("-%d",++scount);
  214.                             outmod(PHA);
  215.                             }
  216.                         else  {
  217.                             cptr -= SECSIZ;
  218.                             free += SECSIZ;
  219.                             printf("\nChecksum error. Retrying <%d>\n",scount+1);
  220.                             outmod(PHA);
  221.                             timoutf = 0;
  222.                             }
  223.                         }
  224.                     }
  225.                 }
  226.             }
  227.         if (kbready()) {
  228.             c = getch();
  229.             if (c != SPECIAL) {
  230.                 if (pflag || (!tflag && !(rflag && chflag))) {
  231.                     outmod(c);
  232.                     if (dodflag) 
  233.                         display(c);
  234.                     }
  235.                 }
  236.             else special();
  237.             }
  238.     }
  239. }
  240.  
  241.  
  242. /*
  243.     place for special.c
  244. */
  245.  
  246. /*
  247.     Handle special Telnet command:
  248. */
  249.  
  250. special()
  251. {
  252.     char c;
  253.     int nn,n;
  254.  
  255.     printf("\n?: ");
  256.     if ( (c = getchar()) != NL) printf("...");
  257.     if(c==SPECIAL) {
  258.         outmod(SPECIAL);
  259.         printf("Current Escape 0x%02x sent", SPECIAL) ;
  260.         }
  261.     else switch (toupper(c)) {
  262.         case 'E' :    
  263.             printf("Current Escape Character: 0x%02x\n",SPECIAL);
  264.             printf("Enter New Escape Character: ");
  265.             SPECIAL=getchar();
  266.             putchar(NL);
  267.             break;
  268.  
  269.         case '7':
  270.             spflag = ask("Strip parity");
  271.             break;
  272.  
  273.         case 'B':
  274.             dobauds();
  275.             break;
  276.  
  277.         case 'N':
  278.             nflag = ask("Recognize incoming nulls");
  279.             break;
  280.  
  281.         case 'F':
  282.             fflag = ask("Transmit CR-LF pairs as CR only");
  283.             break;
  284.  
  285.         case 'H':
  286.             if (rflag || tflag)  { 
  287.                 printf("Must abort transfer first\n");
  288.                 break;
  289.                 }
  290.             hd_sav = hdflag = ask ("Half Duplex");
  291.             reset();
  292.             break;
  293.  
  294.         case 'Z':
  295.             puts(CLEARS) ;
  296.             break;
  297.  
  298.         case 'P':
  299.             if (pflag) 
  300.                 printf("Already pausing");
  301.             else if (!(tflag || rflag)